home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Language/OS - Multiplatform Resource Library
/
LANGUAGE OS.iso
/
lisp
/
elk-2_0.lha
/
elk-2.0
/
src
/
stab.hp9k300.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-10-21
|
3KB
|
110 lines
#include <a.out.h>
#include <sys/types.h>
extern char *malloc(), *realloc();
/* On the HP9000 an nlist entry contains a fixed length
* part consisting of the symbol information, plus a variable
* length part, the name without a '\0' terminator.
* We don't know how much space to allocate for the names
* until we have read them all.
* The solution here is to save all the names on the fly
* in a table that is grown in units of STRING_BLOCK bytes,
* using realloc to expand it on demand.
*/
#define STRING_BLOCK 8192
char *Safe_Realloc (ptr, size) char *ptr; int size; {
char *ret;
ret = ptr ? (char *)realloc( ptr, size ) : (char *)malloc( size );
if (ret == 0)
Primitive_Error ("not enough memory to allocate ~s bytes",
Make_Fixnum (size));
return ret;
}
SYMTAB *Snarf_Symbols (f, ep) FILE *f; struct exec *ep; {
SYMTAB *tab;
register SYM *sp;
register SYM **nextp;
int strsiz = 0; /* running total length of names read, */
/* each '\0' terminated */
int nread = 0; /* running total of bytes read from symbol table */
int max = 0; /* current maximum size of name table */
char *names = 0; /* the name table */
struct nlist_ nl;
tab = (SYMTAB *)Safe_Malloc (sizeof (SYMTAB));
tab->first = 0;
tab->strings = 0;
nextp = &tab->first;
(void)fseek (f, (long)LESYM_OFFSET(*ep), 0);
while (nread < ep->a_lesyms) {
if (fread ((char *)&nl, sizeof (nl), 1, f) != 1) {
Free_Symbols (tab);
(void)fclose (f);
Primitive_Error ("corrupt symbol table in object file");
}
nread += sizeof( nl );
if (nl.n_length == 0) {
continue;
}
else if (nl.n_length + strsiz + 1 > max) {
max += STRING_BLOCK;
names = Safe_Realloc( names, max );
}
if (fread( names + strsiz, 1, nl.n_length, f ) != nl.n_length) {
Free_Symbols (tab);
(void)fclose (f);
Primitive_Error ("corrupt symbol table in object file");
}
else {
nread += nl.n_length;
names[ strsiz + nl.n_length ] = '\0';
}
if ((nl.n_type & N_TYPE) != N_TEXT) {
strsiz += nl.n_length +1;
continue;
}
sp = (SYM *)Safe_Malloc (sizeof (SYM));
sp->name = (char *)strsiz;
strsiz += (nl.n_length + 1);
sp->value = nl.n_value;
*nextp = sp;
nextp = &sp->next;
*nextp = 0;
}
tab->strings = names;
for (sp = tab->first; sp; sp = sp->next)
sp->name += (unsigned)names;
return tab;
}
#ifdef INIT_OBJECTS
SYMTAB *Open_File_And_Snarf_Symbols (name) char *name; {
struct exec hdr;
FILE *f;
SYMTAB *tab;
if ((f = fopen (name, "r")) == NULL)
Primitive_Error ("can't open a.out file");
if (fread ((char *)&hdr, sizeof hdr, 1, f) != 1) {
(void)fclose (f);
Primitive_Error ("can't read a.out header");
}
tab = Snarf_Symbols (f, &hdr);
(void)fclose (f);
return tab;
}
#endif /* INIT_OBJECTS */